package file_reader

import (
	"bufio"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"github.com/fsnotify/fsnotify"
)

// LineReader 定义按行读取文件的接口
type LineReader interface {
	Read() (string, error)
}

// FileLineReader 实现 LineReader 接口的结构体
type FileLineReader struct {
	lines   []string
	index   int
	watcher *fsnotify.Watcher
	readDir string // 新增字段，存储指定读取文件的目录
}

// NewFileLineReader 创建一个新的 FileLineReader 实例
func NewFileLineReader(readDir string) (*FileLineReader, error) {
	// 创建文件监听器
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		return nil, err
	}

	flr := &FileLineReader{
		watcher: watcher,
		readDir: readDir, // 初始化指定目录
	}

	// 初始加载文件
	if err := flr.loadFiles(); err != nil {
		watcher.Close()
		return nil, err
	}

	// 启动文件监听协程
	go flr.watchFiles()

	return flr, nil
}

// loadFiles 加载指定目录下符合条件的文件
func (flr *FileLineReader) loadFiles() error {
	flr.lines = nil
	flr.index = 0

	// 遍历指定目录下的所有文件
	err := filepath.Walk(flr.readDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			fmt.Printf("Error walking path %s: %s\n", path, err)
			return err
		}
		// 忽略目录、以.back 结尾、以. 开头的文件
		if info.IsDir() || strings.HasSuffix(info.Name(), ".back") || strings.HasPrefix(info.Name(), ".") {
			return nil
		}

		// 检查文件权限
		if info.Mode()&0400 == 0 {
			fmt.Printf("No read permission for file: %s\n", path)
			return nil
		}

		// 打开文件
		file, err := os.Open(path)
		if err != nil {
			fmt.Printf("Error opening file %s: %s\n", path, err)
			return err
		}
		defer file.Close()

		// 读取文件的每一行
		scanner := bufio.NewScanner(file)
		// Increase the buffer size
		buf := make([]byte, 0, 64*1024) // Start with 64KB
		scanner.Buffer(buf, 1024*1024)  // Set the maximum buffer size to 1MB

		lineCount := 0
		for scanner.Scan() {
			flr.lines = append(flr.lines, scanner.Text())
			lineCount++
		}
		if err := scanner.Err(); err != nil {
			fmt.Printf("Error reading file %s: %s\n", path, err)
			return err
		}
		fmt.Printf("Read %d lines from file: %s\n", lineCount, path)

		// 添加文件到监听器
		if err := flr.watcher.Add(path); err != nil {
			fmt.Printf("Error adding file %s to watcher: %s\n", path, err)
		}
		return nil
	})

	fmt.Printf("Total lines loaded: %d\n", len(flr.lines))
	return err
}

// watchFiles 监听文件变化
func (flr *FileLineReader) watchFiles() {
	for {
		select {
		case event, ok := <-flr.watcher.Events:
			if !ok {
				return
			}
			if event.Op&fsnotify.Write == fsnotify.Write || event.Op&fsnotify.Create == fsnotify.Create {
				// 文件修改或创建，重新加载文件
				if err := flr.loadFiles(); err != nil {
					fmt.Println("Error reloading files:", err)
				}
			}
		case err, ok := <-flr.watcher.Errors:
			if !ok {
				return
			}
			fmt.Println("Watcher error:", err)
		}
	}
}

// Read 实现 LineReader 接口的 Read 方法
func (flr *FileLineReader) Read() (string, error) {
	if len(flr.lines) == 0 {
		return "", fmt.Errorf("no lines found in files")
	}

	line := flr.lines[flr.index]
	return line, nil
}

// Next 方法用于获取下一行
func (flr *FileLineReader) Next() {
	flr.index = (flr.index + 1) % len(flr.lines)
}
